package com.gscitysfy.cus.drain.modules.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yitter.idgen.YitIdHelper;
import com.gscitysfy.cloudfrmwk.filestrg.MinioConfiguration;
import com.gscitysfy.cloudfrmwk.filestrg.model.MinioResp;
import com.gscitysfy.cus.drain.modules.common.entity.DrainInspectionMnFile;
import com.gscitysfy.cus.drain.modules.common.mapper.DrainInspectionMnFileMapper;
import com.gscitysfy.cus.drain.modules.common.service.IFileService;
import com.gscitysfy.cus.drain.utils.HttpResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author 葛守跃
 * @version 1.0.0
 * @ClassName FileServiceImpl
 * @Description 云文件相关操作
 * @creatTime 2022/3/24 14:56
 */
@Service
@Slf4j
public class FileServiceImpl extends ServiceImpl<DrainInspectionMnFileMapper, DrainInspectionMnFile> implements IFileService {

    @Resource
    private DrainInspectionMnFileMapper fileMapper;

    /**
     * 开发内网文件服务器
     */
    @Value("${pic.route.dev-inner}")
    private String devServerInner;

    /**
     * 测试内网服务器
     */
    @Value("${pic.route.test-inner}")
    private String testServerInner;

    /**
     * 正式内网环境服务器
     */
    @Value("${pic.route.prod-inner}")
    private String prodServerInner;

    /**
     * 开发内网文件服务器
     */
    @Value("${pic.route.dev-out}")
    private String devServerOut;

    /**
     * 测试内网服务器
     */
    @Value("${pic.route.test-out}")
    private String testServerOut;

    /**
     * 正式内网环境服务器
     */
    @Value("${pic.route.prod-out}")
    private String prodServerOut;


    /**
     * 上传文件至minio
     * @param file
     * @return
     */
    @Override
    public DrainInspectionMnFile uploadFile(File file) {
        long fileId = YitIdHelper.nextId();
        MinioResp resp = MinioConfiguration.getMinioService().upload(file, Long.toString(fileId));
        DrainInspectionMnFile commonFile = getCommonFile(resp);
        fileMapper.insert(commonFile);
        return commonFile;
    }

    /**
     * 上传文件至别名为alias配置的服务类
     * @param file
     * @return
     */
    @Override
    public DrainInspectionMnFile uploadFile(File file, String alias) {
        long fileId = YitIdHelper.nextId();
        MinioResp resp = MinioConfiguration.getMinioService(alias).upload(file, Long.toString(fileId));
        DrainInspectionMnFile commonFile = getCommonFile(resp);
        fileMapper.insert(commonFile);
        return commonFile;
    }

    /**
     * 上传文件至minio
     *
     * @param file
     * @return
     */
    @Override
    public DrainInspectionMnFile uploadFile(InputStream file) {
        long fileId = YitIdHelper.nextId();
        MinioResp resp = MinioConfiguration.getMinioService().upload(file, Long.toString(fileId));
        DrainInspectionMnFile commonFile = getCommonFile(resp);
        fileMapper.insert(commonFile);
        return commonFile;
    }

    /**
     * 上传文件至别名为alias配置的服务类
     *
     * @param file
     * @return
     */
    @Override
    public DrainInspectionMnFile uploadFile(InputStream file, String alias) {
        long fileId = YitIdHelper.nextId();
        MinioResp resp = MinioConfiguration.getMinioService(alias).upload(file, Long.toString(fileId));
        DrainInspectionMnFile commonFile = getCommonFile(resp);
        fileMapper.insert(commonFile);
        return commonFile;
    }

    /**
     * 上传文件至文件服务器
     *
     * @param file
     * @return
     */
    @Override
    public DrainInspectionMnFile uploadFile(MultipartFile file) {
        long fileId = YitIdHelper.nextId();
        MinioResp resp = MinioConfiguration.getMinioService().upload(file, Long.toString(fileId));
        DrainInspectionMnFile commonFile = getCommonFile(resp);
        commonFile.setCmFileName(file.getOriginalFilename());
        commonFile.setCmFileType(FileUtil.getSuffix(file.getOriginalFilename()));
        commonFile.setCmFileSize(file.getSize());
        fileMapper.insert(commonFile);
        //为了适应前端附件组件，额外添加两个字段\
        commonFile.setId(commonFile.getCmKid());
        commonFile.setName(file.getOriginalFilename());
        commonFile.setFilePath(resp.getPreviewUrl());

        if(resp.getPreviewUrl().contains(devServerInner)){
            String picUrl = resp.getPreviewUrl().replace(devServerInner, "");
            commonFile.setCmFilePreviewUrlApp(devServerOut + picUrl);
        }else if(resp.getPreviewUrl().contains(testServerInner)){
            String picUrl = resp.getPreviewUrl().replace(testServerInner, "");
            commonFile.setCmFilePreviewUrlApp(testServerOut + picUrl);
        }else if(resp.getPreviewUrl().contains(prodServerInner)){
            String picUrl = resp.getPreviewUrl().replace(prodServerInner, "");
            commonFile.setCmFilePreviewUrlApp(prodServerOut + picUrl);
        }
        return commonFile;
    }

    /**
     * 文件下载
     *
     * @param fileId
     * @return
     */
    @Override
    public ResponseEntity<byte[]> downloadFileByFileId(Long fileId) throws IOException {
        DrainInspectionMnFile file = this.getById(fileId);
        if (!Objects.isNull(file)) {
            InputStream inputStream = MinioConfiguration.getMinioService().getObject(fileId.toString());
            byte[] body = IOUtils.toByteArray(inputStream);
            HttpHeaders headers = HttpResponseUtil.getDownloadHeaders(file.getCmFileName());
            HttpStatus statusCode = HttpStatus.OK;
            return new ResponseEntity<>(body, headers, statusCode);
        }
        return null;
    }

    /**
     * 根据文件ids，获取文件列表
     *
     * @param ids
     * @return
     */
    @Override
    public List<DrainInspectionMnFile> getFileListByIds(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<DrainInspectionMnFile> files = fileMapper.selectFileByList(Arrays.asList(ids.split(StrUtil.COMMA)));
        files.forEach(file -> {
            String filePath = MinioConfiguration.getMinioService().getObjectUrl(file.getCmKid().toString());
            file.setCmFilePreviewUrl(filePath);

            if(file.getCmFilePreviewUrl().contains(devServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(devServerInner, "");
                file.setCmFilePreviewUrlApp(devServerOut + picUrl);
            }else if(file.getCmFilePreviewUrl().contains(testServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(testServerInner, "");
                file.setCmFilePreviewUrlApp(testServerOut + picUrl);
            }else if(file.getCmFilePreviewUrl().contains(prodServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(prodServerInner, "");
                file.setCmFilePreviewUrlApp(prodServerOut + picUrl);
            }
        });
        return files;
    }

    /**
     * 根据文件ids，获取文件列表
     * @param ids
     * @return
     */
    @Override
    public List<DrainInspectionMnFile> getFileListByIds(List<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<DrainInspectionMnFile> files = fileMapper.selectFileByList(ids);
        files.forEach(file -> {
            String filePath = MinioConfiguration.getMinioService().getObjectUrl(file.getCmKid().toString());
            file.setCmFilePreviewUrl(filePath);

            if(file.getCmFilePreviewUrl().contains(devServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(devServerInner, "");
                file.setCmFilePreviewUrlApp(devServerOut + picUrl);
            }else if(file.getCmFilePreviewUrl().contains(testServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(testServerInner, "");
                file.setCmFilePreviewUrlApp(testServerOut + picUrl);
            }else if(file.getCmFilePreviewUrl().contains(prodServerInner)){
                String picUrl = file.getCmFilePreviewUrl().replace(prodServerInner, "");
                file.setCmFilePreviewUrlApp(prodServerOut + picUrl);
            }
        });
        return files;
    }

    /**
     * 根据文件id，获取文件
     *
     * @param id
     * @return
     */
    @Override
    public DrainInspectionMnFile getFileById(Long id) {
        DrainInspectionMnFile file = this.getById(id);
        if (Objects.nonNull(file)) {
            file.setCmFilePreviewUrl(MinioConfiguration.getMinioService().getObjectUrl(id.toString()));
        }
        return file;
    }
}
